package cn.htsyb.synergy.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 *
 * @author lakeside hubin_yuan.410@hotmail.com
 * @version V1.0.0
 * @since 1.0
 * @date 2022/5/11
 */
public class DateUtil {
    public static String PATTERN_GMT = "EEE MMM dd HH:mm:ss z yyyy";
    public static String PATTERN_YMDHMS = "yyyy-MM-dd HH:mm:ss";
    public static String PATTERN_YMD = "yyyy-MM-dd";
    public static String PATTERN_YM = "yyyy-MM";
    public static String PATTERN_Y = "yyyy";
    public static String PATTERN_M = "MM";
    public static String PATTERN_D = "dd";
    public static String PATTERN_HMS = "HH:mm:ss";

    public static long TIME_BASE = 0L;

    public static long TIME_WEEK = 1000 * 7 * 24 * 60 * 60L;
    public static long TIME_DAY = 1000 * 24 * 60 * 60L;
    public static long TIME_HOUR = 1000 * 60 * 60L;
    public static long TIME_MINUTE = 1000 * 60L;

    public static int Calendar_YEAR = Calendar.YEAR;
    public static int Calendar_MONTH = Calendar.MONTH;
    public static int Calendar_DAY = Calendar.DAY_OF_MONTH;
    public static int Calendar_HOUR = Calendar.HOUR_OF_DAY;
    public static int Calendar_MINUTE = Calendar.MINUTE;

    public static Date getCurrDate() {
        return new Date(System.currentTimeMillis());
    }

    public static Long getCurrTimeSpace() {
        return System.currentTimeMillis();
    }

    public static long diffDate(Date srcDate, Date tagDate, Long diff) {
        int YEAR = Calendar.YEAR;
        return (srcDate.getTime() - tagDate.getTime()) / diff;
    }

    public static String getCurrPatternString(String pattern) {
        Date currDate = new Date(System.currentTimeMillis());
        return getPatternString(currDate, pattern);
    }

    public static Date getCurrPatternDate(String pattern) throws ParseException {
        Date currDate = new Date(System.currentTimeMillis());
        return getPatternDate(currDate, pattern);
    }

    public synchronized static String getPatternTimeString(Long time, String pattern) {
        return getPatternString(new Date(time), pattern);
    }

    public synchronized static String getPatternString(Date date, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(date);
    }

    public synchronized static Date getPatternDate(Date date, String pattern) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        String patternDateStr = dateFormat.format(date);
        return dateFormat.parse(patternDateStr);

    }

    public static long getMonthID(Date dateObj) {
        Calendar caleObj = Calendar.getInstance();
        caleObj.setTime(dateObj);
        Calendar srcCaleObj = Calendar.getInstance();
        srcCaleObj.setTimeInMillis(TIME_BASE);
        int yearDiff = caleObj.get(Calendar.YEAR) - srcCaleObj.get(Calendar.YEAR);
        int monthDiff = caleObj.get(Calendar.MONTH) - srcCaleObj.get(Calendar.MONTH);
        return yearDiff * 12 + monthDiff;

    }

    public static long getDayId(Date dateObj) {
        return (dateObj.getTime() - TIME_BASE) / TIME_WEEK;
    }

    public static Date dayIdToDate(int dayID, boolean hasMax) {
        return new Date(dayID * TIME_DAY + TIME_BASE + (hasMax ? (TIME_DAY - 1) : 0));
    }

    public static Date monthIdToDate(int monthID, boolean hasMax) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(TIME_BASE);
        calendar.add(Calendar.MONTH, monthID);
        if (hasMax) {
            calendar.add(Calendar.MONTH, 1);
            calendar.add(Calendar.MILLISECOND, -1);
        }
        return calendar.getTime();
    }

    /**
     * 获取时间周期区间
     *
     * @param date
     * @param calendarMode 支持五种值：Calendar.YEAR|Calendar.MONTH|case Calendar.DAY_OF_MONTH|Calendar.HOUR_OF_DAY|Calendar.MINUTE
     * @return
     */
    public static Date[] getBetweenDate(Date date, int calendarMode) {
        Date[] betweenDate = null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        Calendar minCalendar = Calendar.getInstance();
        minCalendar.setTimeInMillis(0);
        Calendar maxCalendar = Calendar.getInstance();
        maxCalendar.setTimeInMillis(0);

        switch (calendarMode) {
            case Calendar.YEAR: {
                minCalendar.set(year, 0, 1, 0, 0);
                maxCalendar.set(year + 1, 0, 1, 0, 0);
                maxCalendar.add(Calendar.MILLISECOND, -1);
                betweenDate = new Date[]{minCalendar.getTime(), maxCalendar.getTime()};
                break;
            }
            case Calendar.MONTH: {
                minCalendar.set(year, month, 1, 0, 0);
                maxCalendar.set(year, month + 1, 1, 0, 0);
                maxCalendar.add(Calendar.MILLISECOND, -1);
                betweenDate = new Date[]{minCalendar.getTime(), maxCalendar.getTime()};
                break;
            }
            case Calendar.DAY_OF_MONTH: {
                minCalendar.set(year, month, day, 0, 0);
                maxCalendar.set(year, month, day + 1, 0, 0);
                maxCalendar.add(Calendar.MILLISECOND, -1);
                betweenDate = new Date[]{minCalendar.getTime(), maxCalendar.getTime()};
                break;
            }
            case Calendar.HOUR_OF_DAY: {
                minCalendar.set(year, month, day, hour, 0);
                maxCalendar.set(year, month, day, hour + 1, 0);
                maxCalendar.add(Calendar.MILLISECOND, -1);
                betweenDate = new Date[]{minCalendar.getTime(), maxCalendar.getTime()};
                break;
            }
            case Calendar.MINUTE: {
                minCalendar.set(year, month, day, hour, minute);
                maxCalendar.set(year, month, day, hour, minute + 1);
                maxCalendar.add(Calendar.MILLISECOND, -1);
                betweenDate = new Date[]{minCalendar.getTime(), maxCalendar.getTime()};
                break;
            }
            default:
                break;
        }

        return betweenDate;
    }

    public static void main(String[] agrs) {
        Date[] betweenDate = DateUtil.getBetweenDate(new Date(), Calendar.YEAR);
        System.out.println(DateUtil.getPatternString(betweenDate[0], DateUtil.PATTERN_YMDHMS));
        System.out.println(DateUtil.getPatternString(betweenDate[1], DateUtil.PATTERN_YMDHMS));

        betweenDate = DateUtil.getBetweenDate(new Date(), Calendar.MONTH);
        System.out.println(DateUtil.getPatternString(betweenDate[0], DateUtil.PATTERN_YMDHMS));
        System.out.println(DateUtil.getPatternString(betweenDate[1], DateUtil.PATTERN_YMDHMS));

        betweenDate = DateUtil.getBetweenDate(new Date(), Calendar.DATE);
        System.out.println(DateUtil.getPatternString(betweenDate[0], DateUtil.PATTERN_YMDHMS));
        System.out.println(DateUtil.getPatternString(betweenDate[1], DateUtil.PATTERN_YMDHMS));

        betweenDate = DateUtil.getBetweenDate(new Date(), Calendar.HOUR_OF_DAY);
        System.out.println(DateUtil.getPatternString(betweenDate[0], DateUtil.PATTERN_YMDHMS));
        System.out.println(DateUtil.getPatternString(betweenDate[1], DateUtil.PATTERN_YMDHMS));

        betweenDate = DateUtil.getBetweenDate(new Date(), Calendar.MINUTE);
        System.out.println(DateUtil.getPatternString(betweenDate[0], DateUtil.PATTERN_YMDHMS));
        System.out.println(DateUtil.getPatternString(betweenDate[1], DateUtil.PATTERN_YMDHMS));
    }
}
